package org.example.erat.parser;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.example.erat.exception.FileParseException;
import org.example.erat.exception.InvalidFileNameException;
import org.example.erat.log.core.LoggerSingleton;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Excel文件解析器
 * 用于解析.xlsx和.xls文件
 */
public class ExcelFileParser implements FileParser {

    private static final Pattern FILE_NAME_PATTERN = Pattern.compile("(.+)_([0-9]+)_(.+)\\.(xlsx|xls)");

    @Override
    public Map<String, Object> parse(File file) throws IOException {
        LoggerSingleton.getInstance().info("开始解析Excel文档: " + file.getName());

        // 解析文件名
        Map<String, String> fileNameInfo = extractInfoFromFileName(file.getName());
        if (fileNameInfo.isEmpty()) {
            throw new FileParseException("文件名格式不正确: " + file.getName());
        }

        // 解析Excel文件内容
        List<Map<String, Object>> rows = new ArrayList<>();
        try (FileInputStream fis = new FileInputStream(file)) {
            Workbook workbook;

            if (file.getName().endsWith(".xlsx")) {
                workbook = new XSSFWorkbook(fis);
            } else {
                workbook = new HSSFWorkbook(fis);
            }

            Sheet sheet = workbook.getSheetAt(0);
            Row headerRow = sheet.getRow(0);

            // 获取表头
            List<String> headers = new ArrayList<>();
            if (headerRow != null) {
                for (Cell cell : headerRow) {
                    headers.add(cell.getStringCellValue());
                }
            }

            // 读取数据行
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;

                Map<String, Object> rowData = new HashMap<>();
                for (int j = 0; j < headers.size(); j++) {
                    Cell cell = row.getCell(j);
                    if (cell == null) continue;

                    String header = headers.get(j);
                    switch (cell.getCellType()) {
                        case STRING:
                            rowData.put(header, cell.getStringCellValue());
                            break;
                        case NUMERIC:
                            if (DateUtil.isCellDateFormatted(cell)) {
                                rowData.put(header, cell.getDateCellValue());
                            } else {
                                rowData.put(header, cell.getNumericCellValue());
                            }
                            break;
                        case BOOLEAN:
                            rowData.put(header, cell.getBooleanCellValue());
                            break;
                        case FORMULA:
                            rowData.put(header, cell.getCellFormula());
                            break;
                        default:
                            rowData.put(header, "");
                    }
                }
                rows.add(rowData);
            }

            workbook.close();
        }

        Map<String, Object> result = new HashMap<>();
        result.put("fileName", file.getName());
        result.put("filePath", file.getAbsolutePath());
        result.put("fileSize", file.length());
        result.put("rows", rows);
        result.put("experimentName", fileNameInfo.get("experimentName"));
        result.put("studentId", fileNameInfo.get("studentId"));
        result.put("studentName", fileNameInfo.get("studentName"));

        LoggerSingleton.getInstance().info("Excel文档解析完成: " + file.getName() + ", 共 " + rows.size() + " 行数据");
        return result;
    }

    @Override
    public String getSupportedFileType() {
        return "xlsx";
    }

    @Override
    public boolean validateFileName(String fileName) {
        return FILE_NAME_PATTERN.matcher(fileName).matches();
    }

    @Override
    public Map<String, String> extractInfoFromFileName(String fileName) {
        Map<String, String> result = new HashMap<>();

        Matcher matcher = FILE_NAME_PATTERN.matcher(fileName);
        if (matcher.matches()) {
            String experimentName = matcher.group(1);
            String studentId = matcher.group(2);
            String studentName = matcher.group(3);

            result.put("experimentName", experimentName);
            result.put("studentId", studentId);
            result.put("studentName", studentName);
        } else {
            LoggerSingleton.getInstance().warn("文件名格式不正确: " + fileName + "，应为: 实验名_学号_姓名.xlsx或实验名_学号_姓名.xls");
            throw new InvalidFileNameException("文件名格式不正确: " + fileName + "，应为: 实验名_学号_姓名.xlsx或实验名_学号_姓名.xls");
        }

        return result;
    }
}
